#include "ciphertext.h"

Ciphertext::Ciphertext() : ax(nullptr), bx(nullptr), N(0), slots(0), l(0), scale(0) {}

Ciphertext::Ciphertext(uint64_t *ax, uint64_t *bx, long N, long slots, long l, __uint128_t scale)
    : ax(ax), bx(bx), N(N), slots(slots), l(l), scale(scale)
{}

Ciphertext::Ciphertext(const Ciphertext &cipher) : N(cipher.N), slots(cipher.slots), l(cipher.l), scale(cipher.scale)
{
    ax = new uint64_t[N * l];
    bx = new uint64_t[N * l];
    for (long i = 0; i < N * l; i++) {
        ax[i] = cipher.ax[i];
        bx[i] = cipher.bx[i];
    }
}

Ciphertext::Ciphertext(long N, long slots, long l, __uint128_t scale)
    : N(N), slots(slots), l(l), scale(scale) {
    ax = new uint64_t[N * l];
    bx = new uint64_t[N * l];
}

Ciphertext &Ciphertext::operator = (const Ciphertext &o)
{
    if (this == &o) {
        return *this;
    }
    delete[] ax;
    delete[] bx;
    N = o.N;
    l = o.l;
    slots = o.slots;
    scale = o.scale;
    ax = new uint64_t[N * l];
    bx = new uint64_t[N * l];
    for (long i = 0; i < N * l; i++) {
        ax[i] = o.ax[i];
        bx[i] = o.bx[i];
    }
    return *this;
}

void Ciphertext::Print() const
{
    std::cout << "N: " << N << std::endl;
    std::cout << "slots: " << slots << std::endl;
    std::cout << "l: " << l << std::endl;
    std::cout << "ax:" << std::endl;
    for (long i = 0; i < l; i++) {
        for (int j = 0; j < 8; j++) {
            printf("%lu, ", ax[i * N + j]);
        }
        printf("\n");
    }
    std::cout << std::endl;

    std::cout << "bx_CAE:" << std::endl;
    for (long i = 0; i < l; i++) {
        for (int j = 0; j < 8; j++) {
            printf("%lu, ", bx[i * N + j]);
        }
        printf("\n");
    }
    std::cout << std::endl;
}
